﻿using System;
using System.Drawing;
using System.Windows.Forms;
using NetWorkSpeedMonitor;
using System.Threading;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using Maintenance.Util;
using Microsoft.VisualBasic.Devices;
using Microsoft.Win32;
using System.Net;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

namespace Maintenance
{
    public partial class MiniForm : Form
    {
        private BigForm bigForm = null;
        private NetworkAdapter[] adapters;
        private Thread monitorMemoryThread = null;
        private Thread monitorNetworkThread = null;
        private AppConfig config = new AppConfig();
        private MemoryInfo memoryInfo = new MemoryInfo();
        private Point mouseOffset;
        private ToolStripMenuItem currentOpacityItem = null;
        public MiniFormLocation miniFormLocation;
        private string url = "http://192.168.0.3:8000/maintenance/";
        private int rotationTime = 20 * 1000;
        private bool isMouseDown = false;
        public bool isMouseEnter = false;
        public int miniBigFormSpace = 2;
        public int miniFormWidth = 47;
        public int miniFormHeight = 47;
        public int idleSecond = 0;//默认空闲时间

        /*移动时小球出现在bigForm窗体的位置方向枚举*/

        public enum MiniFormLocation
        {
            topLeft,
            topRigh,
            bottomLeft,
            bottomRight
        }

        public MiniForm()
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            //StartupSetting.autoRun("Maintenance.exe", Application.ExecutablePath);
            initParameter();
            // StartMonitorNetwork(); //初始化网络流量监控
        }

        public void initParameter()
        {
            config.loadConfigFile(); //加载配置文件
            currentOpacityItem = getCurrentOpacityItem(config.getOpacity());
            setOpacity(currentOpacityItem, config.getOpacity()); //设置透明度
            Location = config.getMiniBallInitLocation(); //设置小球的坐标
            TopMost = config.getTopMost();
            if (TopMost)
            {
                showStyle2.Image = new Bitmap(Properties.Resources.dot);
                showStyle1.Image = null;
            }
            else
            {
                showStyle1.Image = new Bitmap(Properties.Resources.dot);
                showStyle2.Image = null;
            }
            /*FrmMessage frmMessage = new FrmMessage();
            frmMessage.Show();*/
            try
            {
                string data = url + "application.json";
                WebClient webpage = new WebClient();
                var Json = webpage.DownloadString(data);
                JObject json = (JObject)JsonConvert.DeserializeObject(Json);
                if ((int)json["idleTime"] == 0)
                {
                    idleSecond = int.Parse(PublicGlobal.appConfigure.GetConfigureValue("Maintenance", "idleTime", "300"));
                }
                else
                {
                    idleSecond = (int)json["idleTime"];
                }
                if ((int)json["rotationTime"] == 0)
                {
                    rotationTime = int.Parse(PublicGlobal.appConfigure.GetConfigureValue("Maintenance", "rotationTime", "20")) * 1000;
                }
                else
                {
                    rotationTime = (int)json["rotationTime"] * 1000;
                }
            }
            catch (Exception ex)
            {
                rotationTime = int.Parse(PublicGlobal.appConfigure.GetConfigureValue("Maintenance", "rotationTime", "20")) * 1000;
                idleSecond = int.Parse(PublicGlobal.appConfigure.GetConfigureValue("Maintenance", "idleTime", "300"));
                PublicGlobal.logger.Error("获取公共配置文件失败" + ex.Message);
            };
            this.autoUpdateTime.Start();
            this.autoUpdateApp.Start();
            PublicGlobal.autoOut = false;
        }

        #region 小球的右键菜单单击事件

        /*退出程序*/

        private void quit_Click(object sender, EventArgs e)
        {
            config.saveInfos(this.Location.X, this.Location.Y, (int)(this.Opacity * 100), this.TopMost);
            this.Close();
        }

        /*显示或隐藏所有窗口*/

        private void showhide_Click(object sender, EventArgs e)
        {
            if (showhide.Text == "隐藏")
            {
                this.Hide();
                if (bigForm != null && bigForm.Visible)
                    bigForm.Hide();
                showhide.Text = "显示";
            }
            else
            {
                this.Show();
                showhide.Text = "隐藏";
            }
        }

        private void showStyle1_Click(object sender, EventArgs e)
        {
            showStyle1.Image = new Bitmap(Properties.Resources.dot);
            showStyle2.Image = null;
            this.TopMost = false;
            if (bigForm != null)
            {
                bigForm.TopMost = false;
            }
        }

        private void showStyle2_Click(object sender, EventArgs e)
        {
            showStyle2.Image = new Bitmap(Properties.Resources.dot);
            showStyle1.Image = null;
            this.TopMost = true;
            if (bigForm != null)
            {
                bigForm.TopMost = true;
            }
        }

        private void opacity100_Click(object sender, EventArgs e)
        {
            setOpacity(opacity100, 100);
        }

        private void opacity95_Click(object sender, EventArgs e)
        {
            setOpacity(opacity95, 95);
        }

        private void opacity85_Click(object sender, EventArgs e)
        {
            setOpacity(opacity85, 85);
        }

        private void opacity80_Click(object sender, EventArgs e)
        {
            setOpacity(opacity80, 80);
        }

        private void opacity75_Click(object sender, EventArgs e)
        {
            setOpacity(opacity75, 75);
        }

        private void opacity50_Click(object sender, EventArgs e)
        {
            setOpacity(opacity50, 50);
        }

        private void opacity25_Click(object sender, EventArgs e)
        {
            setOpacity(opacity25, 25);
        }

        /*设置窗体的透明度*/

        private void setOpacity(ToolStripMenuItem opacityItem, int opacity)
        {
            currentOpacityItem.Image = null;
            opacityItem.Image = new Bitmap(Properties.Resources.dot);
            this.Opacity = opacity * 0.01;
            if (bigForm != null)
            {
                bigForm.Opacity = opacity * 0.01;
            }
            currentOpacityItem = opacityItem;
        }

        private ToolStripMenuItem getCurrentOpacityItem(int opacity)
        {
            switch (opacity)
            {
                case 100: return opacity100;
                case 95: return opacity95;
                case 85: return opacity85;
                case 80: return opacity80;
                case 75: return opacity75;
                case 50: return opacity50;
                case 25: return opacity25;
                default: return opacity100;
            }
        }

        #endregion 小球的右键菜单单击事件

        #region 小球的鼠标事件

        private void miniBigFormSpace_MouseEnter(object sender, EventArgs e)
        {
            isMouseEnter = true;
            if (bigForm == null || !bigForm.Visible)
                showDetailFormTimer.Enabled = true;
        }

        private void miniBigFormSpace_MouseLeave(object sender, EventArgs e)
        {
            Point p = MousePosition;
            if (p.X - 10 <= this.Left || p.X + 10 >= this.Left + miniFormWidth || p.Y - 10 <= this.Top || p.Y + 10 >= this.Bottom)
            {
                isMouseEnter = false;
                hideDetailFormTimer.Enabled = true;
            }
        }

        private void miniBigFormSpace_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = true;
                mouseOffset = new Point(MousePosition.X - this.Location.X, MousePosition.Y - this.Location.Y);
                this.Cursor = Cursors.SizeAll;
            }
        }

        private void miniBigFormSpace_MouseUp(object sender, MouseEventArgs e)
        {
            isMouseDown = false;
            this.Cursor = Cursors.Default;
        }

        private void miniBigFormSpace_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseDown == true)
            {
                Point old = this.Location;
                this.Location = getMiniBallMoveLocation();
                if (old.X != this.Location.X || old.Y != this.Location.Y)
                {
                    if (bigForm != null && bigForm.Visible)
                        hideDetailsForm();
                }
                else
                {
                    if (bigForm != null && !bigForm.Visible)
                    {
                        isMouseEnter = true;
                        showDetailFormTimer.Enabled = true;
                    }
                }
            }
        }

        #endregion 小球的鼠标事件

        #region 小球和bigForm的位置方法

        /*小球出现的位置*/

        private Point getMiniBallMoveLocation()
        {
            int x = MousePosition.X - mouseOffset.X;
            int y = MousePosition.Y - mouseOffset.Y;
            if (x < 0)
            {
                x = 0;
            }
            if (y < 0)
            {
                y = 0;
            }
            if (Screen.PrimaryScreen.WorkingArea.Width - x < miniFormWidth)
            {
                x = Screen.PrimaryScreen.WorkingArea.Width - miniFormWidth;
            }
            if (Screen.PrimaryScreen.WorkingArea.Height - y < miniFormHeight)
            {
                y = Screen.PrimaryScreen.WorkingArea.Height - miniFormHeight;
            }
            return new Point(x, y);
        }

        /*获取bigForm出现的位置*/

        private Point getDetailsFormLocation()
        {
            int x = 0, y = 0;
            Point miniBallLocation = this.Location;
            if (this.Location.Y >= bigForm.Height) //minBall在bigBall下面
            {
                if (Screen.PrimaryScreen.WorkingArea.Width - this.Location.X <= bigForm.Width)
                {
                    x = this.Location.X + miniFormWidth - bigForm.Width;
                    miniFormLocation = MiniFormLocation.bottomRight;
                }
                else
                {
                    x = this.Location.X;
                    miniFormLocation = MiniFormLocation.bottomLeft;
                }
                y = this.Location.Y - bigForm.Height - miniBigFormSpace;
            }
            else if (this.Location.Y < bigForm.Height) //minBall在bigBall上面
            {
                if (Screen.PrimaryScreen.WorkingArea.Width - this.Location.X > bigForm.Width)
                {
                    x = this.Location.X;
                    miniFormLocation = MiniFormLocation.topLeft;
                }
                else
                {
                    x = this.Location.X + miniFormWidth - bigForm.Width;
                    miniFormLocation = MiniFormLocation.topRigh;
                }
                y = this.Location.Y + miniFormHeight + miniBigFormSpace;
            }
            return new Point(x, y);
        }

        #endregion 小球和bigForm的位置方法

        #region 显示和隐藏detailForm的方法和定时器

        /*隐藏bigForm*/

        private void hideDetailsForm()
        {
            if (bigForm != null && bigForm.Visible)
            {
                bigForm.Hide();
            }
        }

        /*显示bigForm*/

        private void showDetailsForm()
        {
            if (bigForm == null)
            {
                bigForm = new BigForm(this);
                bigForm.Show();
                bigForm.Opacity = this.Opacity;
                bigForm.Location = getDetailsFormLocation();
            }
            else if (!bigForm.Visible)
            {
                bigForm.Location = getDetailsFormLocation();
                bigForm.Show();
            }
        }

        /*显示bigForm的定时器*/

        private void showDetailFormTimer_Tick(object sender, EventArgs e)
        {
            if (isMouseEnter && !mainContextMenu.Visible)
            {
                showDetailsForm();
            }
            showDetailFormTimer.Enabled = false;
        }

        /*隐藏bigForm的定时器*/

        private void hideDetailFormTimer_Tick(object sender, EventArgs e)
        {
            hideDetailFormTimer.Enabled = false;
            if (bigForm != null && bigForm.Visible && !bigForm.isMouseEnter && !isMouseEnter)
            {
                hideDetailsForm();
            }
            if (bigForm != null && bigForm.isMouseEnter)
                isMouseEnter = false;
        }

        #endregion 显示和隐藏detailForm的方法和定时器

        private KeyMouseHookHelper.GlobalHook hook;

        private void MiniForm_Load(object sender, EventArgs e)
        {
            if (PublicGlobal.CheckUpdate())
            {
                PublicGlobal.StartUpdate();
            }
            //更新的定时器
            idleTimer.Interval = 200;
            idleTimer.Tick += IdleTimer_Tick;
            idleTimer.Enabled = true;
            //初始化钩子对象
            if (hook == null)
            {
                hook = new KeyMouseHookHelper.GlobalHook();
                hook.KeyDown += Hook_KeyDown;
                hook.OnMouseActivity += Hook_OnMouseActivity; ;
            }
            if (!hook.Start())
            {
                PublicGlobal.logger.Error("全局钩子安装失败，请确认是否权限问题");
                MessageBox.Show("安装钩子失败!");
            }

            this.tsmi_version.Text = "当前版本(V" + PublicGlobal.currentVersion + ")";
            SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
        }

        private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            if (e.Reason == SessionSwitchReason.SessionUnlock)
            {
                StartMonitor();//开始监控
            }
        }

        private void Hook_KeyDown(object sender, KeyEventArgs e)
        {
            PublicGlobal.TickCount = 0;
            PublicGlobal.HideScreenProtect();
        }

        private void Hook_OnMouseActivity(object sender, MouseEventArgs e)
        {
            PublicGlobal.TickCount = 0;
            PublicGlobal.HideScreenProtect();
        }

        private void IdleTimer_Tick(object sender, EventArgs e)
        {
            //计算时间，系统锁屏功能
            if (!PublicGlobal.IsProtectScreenShow())//没有屏保就空闲计数
            {
                PublicGlobal.TickCount++;//全局变量计数+1
                //如果计时达到系统锁屏时间
                if (PublicGlobal.TickCount * idleTimer.Interval >= idleSecond * 1000)//1000ms除以计时器间隔(这里间隔是200ms)
                {
                    PublicGlobal.TickCount = 0;//重置空闲计数
                    PublicGlobal.logger.Debug("空闲" + idleSecond + "秒到了，执行锁屏");
                    PublicGlobal.ShowScreenProtect(this, rotationTime); //执行锁屏
                }
            }
        }

        private void MiniForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!PublicGlobal.autoOut)
            {
                FrmCheckPwd frmCheckPwd = new FrmCheckPwd();
                if (frmCheckPwd.ShowDialog() != DialogResult.Yes)
                {
                    e.Cancel = true;
                    return;
                }
                notifyIcon.Dispose();
                if (hook != null)
                    hook.Stop();
            }
        }

        private void tsmi_lock_Click(object sender, EventArgs e)
        {
            PublicGlobal.logger.Debug("手动锁屏");
            idleTimer.Enabled = false;
            PublicGlobal.ShowScreenProtect(this, rotationTime);
            idleTimer.Enabled = true;
        }

        private void timerCheckUpdate_Tick(object sender, EventArgs e)
        {
            PublicGlobal.logger.Debug("检查是否有新版本更新");
            if (PublicGlobal.CheckUpdate())
            {
                PublicGlobal.logger.Debug("有新版本，启动更新");
                PublicGlobal.StartUpdate();
            }
        }

        private void tsmi_checkupdate_Click(object sender, EventArgs e)
        {
            PublicGlobal.logger.Debug("检查是否有新版本更新");
            if (PublicGlobal.CheckUpdate())
            {
                PublicGlobal.logger.Debug("有新版本，启动更新");
                PublicGlobal.StartUpdate();
            }
            else
            {
                MessageBox.Show("未检测到新的版本！");
            }
        }

        public void StartMonitor()
        {
            PublicGlobal.logger.Debug("解锁锁屏后，启动空闲定时器监控");
            PublicGlobal.TickCount = 0;
            this.updateTime();
            idleTimer.Start();
        }

        /// <summary>
        /// 锁屏以后，避免锁屏完了，有触发了屏保，导致需要输入2次锁屏密码
        /// 弹出锁屏后，需要关闭空闲检测定时器。
        /// 当解锁锁屏后，检测鼠标和键盘的移动后，再启动空闲检测。
        /// </summary>
        public void StopMonitor()
        {
            PublicGlobal.logger.Debug("锁屏后，停止空闲定时器监控");
            PublicGlobal.TickCount = 0;
            this.autoUpdateTime.Stop();
            idleTimer.Stop();
        }

        private void autoUpdate_Tick(object sender, EventArgs e)
        {
            this.updateTime();
        }

        //自动同步配置文件中的时间
        public void updateTime()
        {
            if (!this.autoUpdateTime.Enabled)
            {
                this.autoUpdateTime.Stop();
            }
            try
            {
                string data = url + "application.json";
                WebClient webpage = new WebClient();
                var Json = webpage.DownloadString(data);
                JObject json = (JObject)JsonConvert.DeserializeObject(Json);
                if ((int)json["idleTime"] != 0)
                {
                    idleSecond = (int)json["idleTime"];
                }
                if ((int)json["rotationTime"] != 0)
                {
                    rotationTime = (int)json["rotationTime"] * 1000;
                }
            }
            catch (Exception ex)
            {
                PublicGlobal.logger.Error("获取公共配置文件失败," + ex.Message);
            }
            this.autoUpdateTime.Start();
        }

        private void autoUpdateApp_Tick(object sender, EventArgs e)
        {
            PublicGlobal.autoOut = true;
            Application.Exit();
            System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location);
        }
    }
}